package handler;

import java.io.IOException;
import java.util.Date;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import protocal.DataPackage;
import protocal.DataPackage.MessageType;
import service.impl.ChatServiceImpl;

import com.fasterxml.jackson.databind.ObjectMapper;

import data.UserTable;

public class MessageHandler implements Handler{
	
	private final static Logger logger = LogManager.getLogger(MessageHandler.class);
	
	private UserTable userTable;
	private ObjectMapper mapper;
	
	public MessageHandler(){
		userTable = UserTable.getInstance();
		mapper = new ObjectMapper();
	}
	
	
	@Override
	public void handle(Object object) {
			try {
				DataPackage dataPackage = (DataPackage) object;
				handlerLogin(dataPackage);
				handlerLogout(dataPackage);
				handlerMessage(dataPackage);
				handlerShake(dataPackage);
			} catch (IOException e) {
				logger.error(e);
			}
	}
	
	public void handlerLogin(DataPackage dataPackage) throws IOException{
		if (dataPackage.getMessageType()==MessageType.LOGIN) {
			DataPackage dataPackage2 = new DataPackage();
			dataPackage2.setFromeName("\\");
			dataPackage2.setToName(dataPackage.getFromeName());
			dataPackage2.setMessageType(MessageType.LIST);
			dataPackage2.setTime(new Date().getTime());
			StringBuilder stringBuilder = new StringBuilder();
			DataPackage dataPackage3 = new DataPackage();
			dataPackage3.setFromeName("\\");
			dataPackage3.setMessageType(MessageType.LOGIN);
			dataPackage3.setMessageData(dataPackage.getFromeName());
			for (String name:userTable.getUers().keySet()) {
				if (!name.equals(dataPackage.getFromeName())) {
					ChatServiceImpl user = userTable.get(name);
					dataPackage3.setToName(name);
					write(dataPackage3, user);
					stringBuilder.append(name+"\\");
				}
			}
			ChatServiceImpl user = userTable.get(dataPackage.getFromeName());
			dataPackage2.setMessageData(stringBuilder.toString());
			write(dataPackage2, user);
		}
	}
	
	public void handlerLogout(DataPackage dataPackage) throws IOException{
		if (dataPackage.getMessageType()==MessageType.LOGOUT) {
			for (String name:userTable.getUers().keySet()) {
				ChatServiceImpl user = userTable.get(name);
				DataPackage dataPackage3 = new DataPackage();
				dataPackage3.setToName(name);
				dataPackage3.setFromeName("\\");
				dataPackage3.setMessageType(MessageType.LOGOUT);
				dataPackage3.setMessageData(dataPackage.getFromeName());
				write(dataPackage3, user);
			}
		}
	}
	
	public void handlerMessage(DataPackage dataPackage) throws IOException{
		if (dataPackage.getMessageType()!=MessageType.MESSAGE) {
			return;
		}
		if (dataPackage.getToName().equals("\\")) {
			for (String name:userTable.getUers().keySet()) {
				if (!dataPackage.getFromeName().equals(name)) {
					ChatServiceImpl user = userTable.get(name);
					logger.info(dataPackage.toString());
					write(dataPackage, user);
				}
			}
			return;
		}
		ChatServiceImpl user = userTable.get(dataPackage.getToName());
		logger.info(dataPackage.toString());
		write(dataPackage, user);
	}
	
	public void handlerShake(DataPackage dataPackage) throws IOException{
		if (dataPackage.getMessageType()!=MessageType.SHAKE) {
			return;
		}
		if (dataPackage.getToName().equals("\\")) {
			for (String name:userTable.getUers().keySet()) {
				if (!dataPackage.getFromeName().equals(name)) {
					ChatServiceImpl user = userTable.get(name);
					logger.info(dataPackage.toString());
					write(dataPackage, user);
				}
			}
			return;
		}
		ChatServiceImpl user = userTable.get(dataPackage.getToName());
		logger.info(dataPackage.toString());
		write(dataPackage, user);
	}
	
	private void write(DataPackage dataPackage,ChatServiceImpl user) throws IOException{
		user.getWriter().write(mapper.writeValueAsString(dataPackage)+"\n");
		user.getWriter().flush();
	}
	
}
